home *** CD-ROM | disk | FTP | other *** search
/ Aminet 2 / Aminet AMIGA CDROM (1994)(Walnut Creek)[Feb 1994][W.O. 44790-1].iso / Aminet / dev / misc / dialoglib.lha / run.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-09  |  5.7 KB  |  207 lines

  1. #include <dos/dos.h>
  2. #include <intuition/intuition.h>
  3. #include <proto/exec.h>
  4. #include <proto/gadtools.h>
  5. #include <proto/intuition.h>
  6. #include <proto/utility.h>
  7. #include "dialog.h"
  8.  
  9. VOID setDialogWindow( DialogElement *root, struct Window *window )
  10. {
  11.     root->object = window;
  12. }
  13.  
  14. struct Window *getDialogWindow( DialogElement *root )
  15. {
  16.     return root->object;
  17. }
  18.  
  19. /*
  20.  *    will open a window and create the dialog box.
  21.  *    (on the screen specified by DA_Screen as CUSTOMSCREEN; this screen
  22.  *    may not go away until closeDialogWindow() has been called)
  23.  *    The window pointer will be stored in the root element's object field.
  24.  *    Returns window's UserPort or NULL if failure.
  25.  */
  26. ULONG openDialogWindowA( DialogElement *root, struct TagItem *taglist )
  27. {
  28.     LayoutMessage message;
  29.     struct Screen *screen;
  30.     struct Window *window = NULL;
  31.     struct Gadget *glist = NULL, *prev;
  32.     LONG width, winwidth, height, winheight;
  33.     STRPTR title;
  34.     ULONG error = DIALOGERR_BAD_ARGS;
  35.  
  36.     if( !root )
  37.         goto failure;
  38.  
  39.     screen = (struct Screen *)GetTagData( DA_Screen, 0, root->taglist );
  40.     if( !screen )
  41.         goto failure;
  42.  
  43.     winwidth = GetTagData( WA_InnerWidth, 0, taglist );
  44.     winheight = GetTagData( WA_InnerHeight, 0, taglist );
  45.  
  46.     setupDialogElement( root );
  47.  
  48.     width = getMinWidth( root );
  49.     if( width < winwidth )
  50.         width = winwidth;
  51.     prepareLayoutNoVBaseline( &message, width );
  52.  
  53.     height = getMinHeight( root );
  54.     if( height < winheight )
  55.         height = winheight;
  56.     prepareLayoutNoHBaseline( &message, height );
  57.  
  58.     error = DIALOGERR_NO_MEMORY;
  59.  
  60.     title = (STRPTR)GetTagData( WA_Title, 0, root->taglist );
  61.     title = (STRPTR)GetTagData( WA_Title, (ULONG)title, taglist );
  62.  
  63.     window = OpenWindowTags( NULL,
  64.                 ( title ) ? WA_Title : TAG_IGNORE, title,
  65.                 WA_Left, GetTagData( WA_Left, ( screen->Width - width ) / 2, taglist ),
  66.                 WA_Top, GetTagData( WA_Top, ( screen->Height - height ) / 2, taglist ),
  67.                 WA_InnerWidth, width,
  68.                 WA_InnerHeight, height,
  69.                 WA_IDCMP, root->idcmp_mask,
  70.                 WA_SimpleRefresh, TRUE,
  71.                 WA_CustomScreen, screen,
  72.                 TAG_MORE, root->taglist );
  73.     if( !window )
  74.         goto failure;
  75.  
  76.     window->UserData = NULL;
  77.  
  78.     prepareLayoutX( &message, window->BorderLeft );
  79.     prepareLayoutY( &message, window->BorderTop );
  80.  
  81.     prev = CreateContext( &glist );
  82.     if( !prev )
  83.         goto failure;
  84.  
  85.     error = layoutDialogElement( root, &message, &prev );
  86.     if( error )
  87.         goto failure;
  88.  
  89.     AddGList( window, glist, ~0, -1, NULL );
  90.     RefreshGList( glist, window, NULL, -1 );
  91.     GT_RefreshWindow( window, NULL );
  92.  
  93.     window->UserData = (BYTE *)glist;
  94.     setDialogWindow( root, window );
  95.  
  96.     return DIALOGERR_OK;
  97. failure:
  98.     FreeGadgets( glist );
  99.     clearDialogElement( root );
  100.     if( window )
  101.         CloseWindow( window );
  102.     return error;
  103. }
  104.  
  105. ULONG openDialogWindow( DialogElement *root, ULONG first, ... )
  106. {
  107.     return openDialogWindowA( root, (struct TagItem *)&first );
  108. }
  109.  
  110. VOID closeDialogWindow( DialogElement *root )
  111. {
  112.     struct Window *window;
  113.  
  114.     if( window = getDialogWindow( root ) )
  115.     {
  116.         struct Gadget *glist = (struct Gadget *)window->UserData;
  117.  
  118.         CloseWindow( window );
  119.         setDialogWindow( root, NULL );
  120.  
  121.         FreeGadgets( glist );
  122.         clearDialogElement( root );
  123.     }
  124. }
  125.  
  126. /*
  127.  *    conducts a simple dialog.
  128.  *    The dialog is called simple because elements (buttons etc.) cannot trigger
  129.  *    complex actions.
  130.  *    We simply let the user play with the gadgets until one is activated that
  131.  *    has the DA_Termination flag set.
  132.  *    Then we leave the event loop and return the terminating element.
  133.  *    Note however that by means of the DA_SubDialogRoot attribute, an element
  134.  *    can invoke runSimpleDialog() recursively to run a subdialog when activated.
  135.  *    The termination result of that subdialog is stored in the location
  136.  *    specified by DA_Storage (if there).
  137.  *    Although this system allows for quite complex dialogs, you still may need
  138.  *    to do your own event processing in certain cases.
  139.  *    In particular, using runSimpleDialog() you cannot take action depending on
  140.  *    the terminating element of a subdialog immediately. After the topmost
  141.  *    runSimpleDialog() invocation returns control to you, it is impossible
  142.  *    to tell how often exactly the subdialog was run and how it was terminated
  143.  *    each time.
  144.  *    Use runSimpleDialog() as a model from which to start writing your event
  145.  *    handler. Add your code immediately before the call to GT_ReplyIMsg().
  146.  *    At that point of control flow you can examine the match variable to see
  147.  *    which dialog element was activated by the event (if any).
  148.  */
  149. DialogElement *runSimpleDialogA( DialogElement *root, struct TagItem *taglist )
  150. {
  151.     struct IntuiMessage *imsg;
  152.     DialogElement *terminator = NULL;
  153.     struct Window *window;
  154.     struct MsgPort *idcmp;
  155.     ULONG error, idcmp_sigmask, received, run;
  156.  
  157.     if( !root )
  158.         return NULL;
  159.  
  160.     error = openDialogWindowA( root, taglist );
  161.     if( error )
  162.         goto cleanup;
  163.  
  164.     window = getDialogWindow( root );
  165.     idcmp = window->UserPort;
  166.     idcmp_sigmask = ( idcmp ) ? 1L << idcmp->mp_SigBit : 0;
  167.  
  168.     run = TRUE;
  169.     do
  170.     {
  171.         received = Wait( SIGBREAKF_CTRL_C | idcmp_sigmask );
  172.         if( received & SIGBREAKF_CTRL_C )
  173.             run = FALSE;
  174.         if( received & idcmp_sigmask )
  175.             while( imsg = GT_GetIMsg( idcmp ) )
  176.             {
  177.                 DialogElement *match;
  178.  
  179. #ifdef DEBUG1
  180.                 printf( "runSimpleDialog : found IMsg %08lx in IDCMP %08lx\n", imsg, idcmp );
  181. #endif
  182.                 match = mapDialogEvent( root, imsg );
  183.                 if( match )
  184.                     if( GetTagData( DA_Termination, 0, match->taglist ) )
  185.                     {
  186.                         terminator = match;
  187.                         run = FALSE;
  188.                     }
  189.                 /*** to run a custom dialog, insert additional event processing here ***/
  190.                 GT_ReplyIMsg( imsg );
  191. #ifdef DEBUG1
  192.                 printf( "runSimpleDialog : replied to IMsg %08lx\n", imsg );
  193. #endif
  194.             }
  195.     }
  196.     while( run );
  197. cleanup:
  198.     if( !error )
  199.         closeDialogWindow( root );
  200.     return terminator;
  201. }
  202.  
  203. DialogElement *runSimpleDialog( DialogElement *root, ULONG first, ... )
  204. {
  205.     return runSimpleDialogA( root, (struct TagItem *)&first );
  206. }
  207.